#include <string.h>
#include "utils.h"
#include "user.h"

// 用户
extern List *user_list;
static uint8_t failed_count = 0;
static uint8_t current_idx = 0;
static const User* user_array[MAX_USER_COUNT];

void add_user(const User* user) {
    int idx = -1;
    // 判断数组里面是否有NULL的一项
    if (current_idx >= MAX_USER_COUNT) {
        for(int i = 0; i < MAX_USER_COUNT; i++) {
            if (user_array[i] == NULL) {
                idx = i;
                break;
            }
        }
    } else {
        idx = current_idx;
        current_idx++;
    }

    if (idx >= 0)
        user_array[idx] = user;
}

int find_user(const char* name, compare cmp) {
    int result = -1;
    const User* t = NULL;
    for(uint8_t i = 0; i < current_idx; i++) {
        t = user_array[i];
        if (cmp(name, t->name) == 0) {
            break;
        }
    }
    return result;
}

int cmp_username(const void* ptr1, const void* ptr2) {
    char* name1 = (char*)ptr1;
    char* name2 = (char*)ptr2;

    return strncmp(name1, name2, MAX_USER_NAME);
}

void delete_user(char* name) {
    int idx = find_user(name, cmp_username);
    if (idx >= 0) {
        user_array[idx] = NULL;
    }
}

void show_user(const void* ptr) {
    const User* user = (User *)ptr;
    printf("用户名：%s \t 性别：%c \t 分数：%d \t 编号：%d \r\n", user->name, user->gender, user->score, user->id);
}

int cmp_user_name(const void* ptr1, const void* ptr2) {
    if (ptr1 == NULL || ptr2 == NULL) {
        return -1;
    }
    const User* user = (User*)ptr1;
    return strncmp(user->name, ptr2, MAX_USERNAME_LENGTH);
}

int cmp_user_passwd(const void* ptr1, const void* ptr2) {
    if (ptr1 == NULL || ptr2 == NULL) {
        return -1;
    }
    const User* user = (User*)ptr1;
    const char* passwd = (char*)ptr2;

    return strncmp(user->passwd, passwd, MAX_PASSWORD_LENGTH);
}

int cmp_user_id(const void* ptr1, const void* ptr2) {
    if (ptr1 == NULL || ptr2 == NULL) {
        return -1;
    }

    const User* u1 = (User*)ptr1;
    const User* u2 = (User*)ptr2;

    if (u1->id > u2->id) {
        return 1;
    } else if (u1->id < u2->id) {
        return -1;
    } else {
        return 0;
    }
}

// 添加用户
void user_add() {
    printf("添加用户\r\n");
    User* user = malloc(sizeof(User));
    printf("请输入用户名：");
    get_str(user->name, MAX_USER_NAME);
    printf("请输入密码：");
    get_pwd(user->passwd, true, MAX_USER_PWD);
    printf("请输入分数：");
    scanf("%d", &user->score);
    printf("请输入性别：");
    user->gender = get_sex();
    printf("请输入编号：");
    scanf("%d", &user->id);
    add_list_tail(user_list, user);
    add_user(user);
}

// 删除用户
void user_del() {
    printf("删除用户\r\n");
    // 根据用户名查找用户
    printf("请输入用户名：");
    char name[MAX_USER_NAME] = {};
    get_str(name, MAX_USER_NAME);

    int index = get_list_node_by_value(user_list, name, cmp_user_name);
    if (index < 0) {
        printf("查无此人\r\n");
        return;
    }

    delete_list_node_by_index(user_list, index);
    delete_user(name);
}

// 修改用户
void user_chg() {
    printf("修改用户\r\n");
    // 找的到用户，先删除该用户，然后在原来索引位置，插入一个新创建的用户
    printf("请输入用户名：");

    User* user = malloc(sizeof(User));
    get_str(user->name, MAX_USER_NAME);

    int index = get_list_node_by_value(user_list, user->name, cmp_user_name);
    if (index < 0) {
        printf("查无此人\r\n");
        return ;
    }
    
    printf("请输入密码：");
    get_pwd(user->passwd, true, MAX_PASSWORD_LENGTH);
    printf("请输入性别：");
    user->gender = get_sex();
    printf("请输入分数：");
    scanf("%d", &user->score);
    printf("请输入编号：");
    scanf("%d", &user->id);

    bool res = delete_list_node_by_index(user_list, index);
    if (res == true) {
        if (insert_list_node(user_list, index, user)) {
            printf("修改用户成功\r\n");
        } else {
            printf("修改用户失败\r\n");
        }
    } else {
        printf("删除用户失败\r\n");
    }
}

// 查询用户
void user_get() {
    printf("查询用户\r\n");
    // 根据用户名查找用户
    // 找不到，查无此人
    printf("请输入用户名：");
    char name[MAX_USER_NAME] = {};
    get_str(name, MAX_USER_NAME);

    int index = get_list_node_by_value(user_list, name, cmp_user_name);
    if (index < 0) {
        printf("查无此人\r\n");
        return;
    }

    show_index(user_list, index, show_user);
}

void user_srt() {
    printf("排序用户\r\n");

    int length = current_idx;
    quick_sort((void **)user_array, length, cmp_user_id);
    for(uint8_t i = 0; i < length; i++) {
        show_user(user_array[i]);
    }
}

void user_shw() {
    printf("显示用户\r\n");
    show_list(user_list, show_user);
}

State user_login(const char* name, const char* password) {
    if (failed_count > 3) {
        return IsLock;
    }

    char name_str[MAX_USERNAME_LENGTH] = {};
    char passwd_str[MAX_PASSWORD_LENGTH] = {};

    strcpy(name_str, name);
    strcpy(passwd_str, password);

    int name_index = get_list_node_by_value(user_list, name_str, cmp_user_name);
    int passwd_index = get_list_node_by_value(user_list, passwd_str, cmp_user_passwd);

    if (name_index < 0) {
        failed_count++;
        return NameError;
    }
    if (passwd_index < 0) {
        failed_count++;
        return PassError;
    }
    failed_count = 0;
    return LoginOk;
}
